
const g = require('../utils/global');
const audioUtils = require('../utils/audioUtils');

cc.Class({
    extends: cc.Component,

    properties: {
        prefabs: {
            type: [cc.Prefab],
            default: [],
        },
        effectLayer: {
            type: cc.Node,
            default: null,
        },
        audioUtils: {
            type: audioUtils,
            default: null,
        },
        // 分数
        score: {
            type: cc.Label,
            default: null,
        }
    },

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        // 动画是否播放中
        this.isPlaying = false;
        // 是否可以交换
        this.isCanMove = true;
        this.score.string = '0';
        this.setLister();
    },

    start () {

    },

    // 设置控制器
    setController(controller) {
        this.controller = controller;
    },

    // 绑定格子数据
    initWithCellModels(cellModels) {
        cc.log('bind cell model');
        this.cellViews = [];
        for(let i = 1; i <= g.GRID_ROWS; ++i) {
            this.cellViews[i] = [];
            for(let j = 1; j <= g.GRID_COLUMNS; ++j) {
                // 设置格子类型
                const type =cellModels[i][j].type;
                const anim = cc.instantiate(this.prefabs[type]);
                anim.parent = this.node;
                // 数据绑定预制体
                const cellView = anim.getComponent('cellView');
                cellView.initWithModel(cellModels[i][j]);
                this.cellViews[i][j] = anim;
            }
        }
    },

    // 监视操作
    setLister: function () {
        cc.log('listening');
        this.node.on(cc.Node.EventType.TOUCH_START, function (eventTouch) {
            if (this.isPlaying) {
                // 动画播放中，不允许点击
                return true
            }
            const touchPos = eventTouch.getLocation();
            const cellPos = this.convertTouchPosToCell(touchPos);
            // cc.log(`click pos = ${cellPos}`);
            if (cellPos) {
                const changeModels = this.selectCell(cellPos);
                this.isCanMove = changeModels.length < 3;
            } else {
                this.isCanMove = false;
            }
        }, this);

        // 滑动效果
        this.node.on(cc.Node.EventType.TOUCH_MOVE, function (eventTouch) {
            if (!this.isCanMove) {
                return true;
            }
            const startTouchPos = eventTouch.getStartLocation();
            const startCellPos = this.convertTouchPosToCell(startTouchPos);
            const touchPos = eventTouch.getLocation();
            const cellPos = this.convertTouchPosToCell(touchPos);
            if(startCellPos.x !== cellPos.x || startCellPos.y !== cellPos.y) {
                this.isCanMove = false;
                this.selectCell(cellPos);
            }
        }, this)
    },

    selectCell: function(cellPos) {
        // 处理逻辑
        const result = this.controller.selectCell(cellPos);
        // 需要改变的格子，包括新生成、马上要摧毁的格子
        const changeModels = result[0];
        const effectQueue = result[1];
        // 播放动效
        this.playEffect(effectQueue);
        this.disableTouch(this.getPlayAniTime(changeModels), this.getStep(effectQueue));
        this.updateView(changeModels);
        this.controller.cleanCmd();
        if(changeModels.length >= 2) {
            this.updateSelect(cc.v2(-1, -1));
            this.audioUtils.playSwap();
        } else {
            this.updateSelect(cellPos);
            this.audioUtils.playClick();
        }
        // 更新分数
        this.updateScore();
        return changeModels;
    },

    updateSelect(pos) {
        for(let i = 1; i <= g.GRID_ROWS; ++i) {
            for(let j = 1; j <= g.GRID_COLUMNS; ++j) {
                if(!this.cellViews[i][j]) {
                    continue;
                }
                const cellView = this.cellViews[i][j].getComponent('cellView');
                if(pos.x === i && pos.y === j) {
                    cellView.setSelect(true);
                } else {
                    cellView.setSelect(false);
                }
            }
        }
    },

    updateView(chaneModels) {
        const newCellView = [];
        for(const model of chaneModels) {
            const viewInfo = this.findViewByModel(model);
            let view = null;
            // 如果原来的cell不存在，则新建
            if(!viewInfo) {
                const type = model.type;
                const aniView = cc.instantiate(this.prefabs[type]);
                aniView.parent = this.node;
                const cellView = aniView.getComponent('cellView');
                cellView.initWithModel(model);
                view = aniView;
            } else {
                view = viewInfo.view;
                // 本 model 已经处理
                this.cellViews[viewInfo.x][viewInfo.y] = null;
            }
            const cellView = view.getComponent('cellView');
            cellView.updateView();
            if(!model.isDeath) {
                newCellView.push({
                    model,
                    view,
                });
            }
        }
        // 重新标记
        newCellView.forEach( elem => {
           const model = elem.model;
           this.cellViews[model.x][model.y] = elem.view;
        }, this);
    },

    // 根据cell的model返回对应的view
    findViewByModel(model) {
        for(let i = 1; i <= g.GRID_ROWS; ++i) {
            for(let j = 1; j <= g.GRID_COLUMNS; ++j) {
                if(this.cellViews[i][j] && this.cellViews[i][j].getComponent('cellView').model === model) {
                    return {view: this.cellViews[i][j], x:i, y:j };
                }
            }
        }
        return null;
    },

    // 一段时间内禁止操作，不需要通过动画播放完后的动作回调
    disableTouch(dt, step) {
        if (dt <= 0) {
            return ;
        }
        this.isPlaying = true;
        this.node.runAction(cc.sequence(cc.delayTime(dt), cc.callFunc(function () {
            this.isPlaying = false;
            this.audioUtils.playContinuousMatch(step);
        }, this)))
    },

    // 根据点击的像素位置，转换成网格中的位置
    convertTouchPosToCell: function(pos) {
        // 将屏幕坐标到节点本地坐标系（相对于父节点坐标）
        pos = this.node.convertToNodeSpaceAR(pos);
        // 判断边界
        if(pos.x < 0 || pos.x >= g.GRID_WIDTH || pos.y < 0 || pos.y >= g.GRID_HEIGHT) {
            return false;
        }
        const y = Math.floor(pos.x / (g.OFFSET_X + g.CELL_WIDTH)) + 1;
        const x = g.GRID_ROWS - Math.floor(pos.y / (g.OFFSET_Y + g.CELL_HEIGHT));
        return cc.v2(x, y);
    },

    // 获取最大播放时间
    getPlayAniTime(changeModels) {
        if(!changeModels) {
            return;
        }
        let maxTime = 0;
        changeModels.forEach(elem => {
            elem.cmd.forEach(cmd => {
                if(maxTime < cmd.playTime + cmd.keepTime) {
                    maxTime = cmd.playTime + cmd.keepTime;
                }
            }, this)
        }, this);
        return maxTime;
    },

    updateScore: function() {
        const score = this.controller.getScore();
        // 100倍分数
        const oldScore = Number(this.score.string);
        const newScore = score*100;
        if (newScore !== oldScore) {
            this.score.string = newScore.toString();
        }
    },

    // 获得爆炸次数， 同一个时间算一个
    getStep(effectQueue) {
        if(!effectQueue) {
            return 0
        }
        // 初始值 0
        return effectQueue.reduce(function (maxVal, effectCmd) {
            return Math.max(maxVal, effectCmd.step || 0);
        }, 0);
    },

    playEffect(effectQueue) {
        this.effectLayer.getComponent('effectLayer').playEffects(effectQueue);
    },

    // update (dt) {},
});
